import UIKit

//枚举语法
enum SomeEnumeration {
    
}

enum CompassPoint {
    case North
    case South
    case East
    case West
}

//一个枚举中被定义的值比如 North, South, East和West是枚举的成员值。case关键字表明新的一行成员值将被定义。注意：不像C或OC,Swift枚举成员在创建时不会被赋予一个默认的整数值。在上面例子中,North, South, East和West不是隐式的等于0,1,2,3.
//多个成员值可以出现在同一行，用逗号隔开
enum Plant {
    case Mercury, Venus, Eath, Mars
}

//每个枚举定义了一个全新的类型
var directionToHead = CompassPoint.West
directionToHead = .East  //directionToHead的类型已知时，当设定它的值时，可以不在写类型名

//匹配枚举值与Switch语句
directionToHead = .South
switch directionToHead {
case .East:
    print("Where the sun raise")
case .North:
    print("Lots of  plannet have a north")
case .South:
    print("Watch out for penguins")
case .West:
    print("Where the skies are blue")
}
//当不需要匹配每个枚举成员时，你可以提供一个默认的default语句来涵盖所有未明确提出的任何成员
let somePlant = Plant.Eath
switch somePlant {
case .Mercury:
    print("Where the sun raise")
case .Mars:
    print("Lots of  plannet have a north")
default:
    print("Not a safe place.")
}

//相关值 有时候能把类型的相关值和成员一起存储起来会很有用。
enum BarCode {
    case UPCA(Int, Int, Int)
    case QRCode(String)
}

//定义一个名为BarCode的枚举类型，它可以是UPCA的一个相关值 (Int,Int,Int)，或者是QRCode的一个字符串类型(String)相关值，这些相关值其实就是元祖。这个定义不提供任何Int或者String的实际值，它只是定义了当BarCode常量和变量等于BarCode.UPCA或BarCode.QRCode时，相关值的类型。

var productBarCode = BarCode.UPCA(8, 85909_51226, 3)
productBarCode = BarCode.QRCode("ABCDEFGHIJKLMNOP")
//条形码的常量和变量可以存储一个.UPCA或者一个.QRCode（连同它的相关值）但在任何指定时间只能存储其中一个。你可以在switch的case分支代码中提取每个相关值作为一个常量(用let前缀)或者作为一个变量(var)来使用。
switch productBarCode {
case .UPCA(let numberSystem, let identifer, let chcek):
    print("numberSystem is \(numberSystem)")
case .QRCode(let produceCode):
    print("QR Code with value of \(produceCode)")
}

//如果一个枚举成员的所有相关值被提取为常量，或者他们全部被提取为变量。为了简洁，你可以只放置一个var 或者 let 标注在成员名称前：
switch productBarCode {
case let .UPCA(numberSystem, identifer, chcek):
    print("numberSystem is \(numberSystem)")
case let .QRCode(produceCode):
    print("QR Code with value of \(produceCode)")
}

//原始值 枚举成员可被默认值（称为原始值）预先填充，其中这些原始值具有相同的类型。
enum ASCIIControlCharacter:Character {
    case Tab = "\t"
    case LineFeed = "\n"
    case CarriageReturn = "\r"
}

enum Plant2 : Int{
    case Mercury = 1, Venus, Earth //后面的枚举成员默认值自动递增
}

//通过rawValue访问
let anotherOrder = Plant2.Earth.rawValue

//视图通过原始值获取枚举成员，init(rawValue:)返回的是可选类型 Plant2?
if let possiblePlant = Plant2.init(rawValue: 3) {
    print(possiblePlant)
}


